/**
  @file     	AL_String.cpp
  @brief    	AL_String: define a new String class
  @author  	arvin
  @version 	1.0   2013/03/13
 */
#include "stdafx.h"

#ifndef CXX_AL_STRING_H
#include "AL_String.h"
#endif

// AL_ErrorLog Recording
static const NCHAR g_szErrorFileInfo[] = NTEXT("$Id: AL_String.cpp 69 2013-10-08 03:03:33Z xiaoting $");
///////////////////////////////////////////////////////////////////////////
//			AL_String
///////////////////////////////////////////////////////////////////////////

/**
* Construction
*
* @param
* @return
*/
AL_String::AL_String()
{
	m_pcData = new NCHAR[1];
	if (NULL != m_pcData) {
		*m_pcData = 0x00;	// 0x00 "\0"
	}
}

/**
* Construction
*
* @param const NCHAR *str = NULL
* @return
*/
AL_String::AL_String(const NCHAR *str)
{
	if(NULL == str) 
	{ 
		m_pcData = new NCHAR[1];
		if (NULL != m_pcData) {
			*m_pcData = 0x00;	// 0x00 "\0"
		}
	}
	else 
	{ 
		DWORD dwLength = static_cast<WORD>(NCHARstrlen(str)); 
		m_pcData = new NCHAR[dwLength+1];
		memset(m_pcData, 0x00, sizeof(NCHAR)*(dwLength+1));
		if (NULL != m_pcData) {
			NCHARstrcpy(m_pcData, str); 
		}
	} 
}

/**
* Destruction
*
* @param
* @return
*/
AL_String::~AL_String()
{

}

/**
*Copy Construct
*
* @param const AL_String &cAL_String
* @return
*/
AL_String::AL_String(const AL_String &cAL_String)
{
	DWORD dwLength = static_cast<WORD>(NCHARstrlen(cAL_String.m_pcData)); 
	m_pcData = new NCHAR[dwLength+1];
	memset(m_pcData, 0x00, sizeof(NCHAR)*(dwLength+1));
	if (NULL != m_pcData) {
		NCHARstrcpy(m_pcData, cAL_String.m_pcData); 
	}
}

/**
*GetString
*
* @param VOID
* @return const NCHAR* 
*/
const NCHAR* 
AL_String::GetString(VOID) const
{
	return m_pcData;
}


/**
*Length
*
* @param
* @return DWORD
*/
DWORD 
AL_String::Length() const
{
	return NCHARstrlen(m_pcData);
}

/**
*Add
*
* @param const NCHAR* ncpChar
* @return VOID
*/
VOID 
AL_String::Add(const NCHAR* ncpChar)
{
	
}

/**
*Add
*
* @param const AL_String& cAL_String
* @return VOID
*/
VOID 
AL_String::Add(const AL_String& cAL_String)
{
	Add(cAL_String.GetString());
}

/**
*Assignment
*
* @param const AL_String &cAL_String
* @return AL_String&
*/
AL_String&
AL_String::operator = (const AL_String &cAL_String)
{
	// (1) Check the self-assignment
	if(this == &cAL_String) {
		return *this;
	}
	// (2) The release of the original memory resources
	if (NULL != m_pcData) {
		delete[] m_pcData;
		m_pcData = NULL;
	}
	// (3)Allocation of memory resources, and copy the contents
	DWORD dwLength = static_cast<WORD>(NCHARstrlen(cAL_String.m_pcData)); 
	m_pcData = new NCHAR[dwLength+1];
	memset(m_pcData, 0x00, sizeof(NCHAR)*(dwLength+1));
	if (NULL != m_pcData) {
		NCHARstrcpy(m_pcData, cAL_String.m_pcData); 
	}
	// (4)Return the object reference
	return *this; 
}

/**
*Overloaded Operators +
*
* @param const AL_String& cAL_String
* @return AL_String
*/
AL_String 
AL_String::operator + (const AL_String& cAL_String) const
{
	AL_String strReturn;
	strReturn += *this;
	strReturn += cAL_String;
	return strReturn;
}

/**
*Overloaded Operators +=
*
* @param const NCHAR* ncpChar
* @return AL_String&
*/
AL_String& 
AL_String::operator += (const NCHAR* ncpChar)
{
	DWORD dwAddLength = NCHARstrlen(ncpChar);
	if (0x00 == dwAddLength) {
		//no data to add
		return *this;
	}
	DWORD dwDataLength = Length();
	//save the data and delete it after copy it 
	const NCHAR* ncpDelete = m_pcData;
	//think about the param may be same memory, so we need to apply a new memory and delete data memory at last
	m_pcData = new NCHAR[dwDataLength+dwAddLength+1];
	memset(m_pcData, 0x00, sizeof(NCHAR)*(dwDataLength+dwAddLength+1));
	NCHARstrcat(m_pcData, ncpDelete);
	NCHARstrcat(m_pcData, ncpChar);

	//free the memory at last
	delete[] ncpDelete;
	ncpDelete = NULL;
	return *this;
}

/**
*Overloaded Operators +=
*
* @param const AL_String& cAL_String
* @return AL_String&
*/
AL_String& 
AL_String::operator += (const AL_String& cAL_String)
{
	return (*this) += cAL_String.GetString();
}

/**
*Overloaded Operators ==
*
* @param const const NCHAR* ncpChar
* @return BOOL	
*/
BOOL 
AL_String::operator == (const NCHAR* ncpChar) const
{
	DWORD dwCnt = 0;
	if (Length() != NCHARstrlen(ncpChar)) {
		return FALSE;
	}
	
	for (DWORD dwCnt=0; dwCnt<Length()+1; dwCnt++) {
		//loop all char
		if (*(m_pcData+dwCnt) != *(ncpChar+dwCnt)) {
			//not the same
			return FALSE;
		}
	}

	return TRUE;
}

/**
*Overloaded Operators ==
*
* @param const AL_String& cAL_String
* @return BOOL	
*/
BOOL 
AL_String::operator == (const AL_String& cAL_String) const
{
	
	if ((*this) == cAL_String.GetString()) {
		return TRUE;
	}

	return FALSE;
}

/**
*Overloaded Operators !=
*
* @param const NCHAR* ncpChar
* @return BOOL
*/
BOOL 
AL_String::operator != (const NCHAR* ncpChar) const
{
	if ((*this) == ncpChar) {
		return FALSE;
	}
	return TRUE;
}

/**
*Overloaded Operators !=
*
* @param const AL_String& cAL_String
* @return BOOL
*/
BOOL 
AL_String::operator != (const AL_String& cAL_String) const
{
	if ((*this) == cAL_String.GetString()) {
		return FALSE;
	}
	return TRUE;
}

/**
*Overloaded Operators <
*
* @param const NCHAR* ncpChar
* @return BOOL
*/
BOOL 
AL_String::operator < (const NCHAR* ncpChar) const
{
	DWORD dwCnt = 0;
	while (('\0' != *(m_pcData+dwCnt))
		|| ('\0' != *(ncpChar+dwCnt))) {
			if (*(m_pcData+dwCnt) < *(ncpChar+dwCnt)) {
				return TRUE;
			}
			else if (*(m_pcData+dwCnt) > *(ncpChar+dwCnt)) {
				return FALSE;
			}
			else {
				//the same
			}
			dwCnt++;
	}
	//all the same compare the length
	if (Length() < NCHARstrlen(ncpChar)) {
		return TRUE;
	}

	return FALSE;
}

/**
*Overloaded Operators <
*
* @param const AL_String& cAL_String
* @return BOOL
*/
BOOL 
AL_String::operator < (const AL_String& cAL_String) const
{
	return (*this) < cAL_String.GetString();
}

/**
*Overloaded Operators >
*
* @param const NCHAR* ncpChar
* @return BOOL
*/
BOOL 
AL_String::operator > (const NCHAR* ncpChar) const
{
	if ((*this) < ncpChar) {
		return FALSE;
	}
	else if ((*this) == ncpChar) {
		return FALSE;
	}
	else {
		;
	}

	return TRUE;
}

/**
*Overloaded Operators >
*
* @param const AL_String& cAL_String
* @return BOOL
*/
BOOL 
AL_String::operator > (const AL_String& cAL_String) const
{
	return (*this) > cAL_String.GetString();
}

/**
*Overloaded Operators <=
*
* @param const NCHAR* ncpChar
* @return BOOL
*/
BOOL 
AL_String::operator <= (const NCHAR* ncpChar) const
{
	if ((*this) > ncpChar) {
		return FALSE;
	}

	return TRUE;
}

/**
*Overloaded Operators <=
*
* @param const AL_String& cAL_String
* @return BOOL
*/
BOOL 
AL_String::operator <= (const AL_String& cAL_String) const
{
	return (*this) <= cAL_String.GetString();
}

/**
*Overloaded Operators >=
*
* @param const NCHAR* ncpChar
* @return BOOL
*/
BOOL 
AL_String::operator >= (const NCHAR* ncpChar) const
{
	if ((*this) < ncpChar) {
		return FALSE;
	}

	return TRUE;
}

/**
*Overloaded Operators >=
*
* @param const AL_String& cAL_String
* @return BOOL
*/
BOOL 
AL_String::operator >= (const AL_String& cAL_String) const
{
	return (*this) >= cAL_String.GetString();
}

/**
*Overloaded Operators []
*
* @param const AL_String& cAL_String
* @return NCHAR
*/
NCHAR 
AL_String::operator[](DWORD dwIndex) const
{
	NCHAR ncReturn = '\0';
	if (dwIndex > Length()) {
		//over the string length
		return ncReturn;
	}

	ncReturn = m_pcData[dwIndex];
	return ncReturn;
}
/* EOF */
